package org.droidcon.droidconapp.news;

/*
 *	This file is part of OI Newsreader.
 *	Copyright (C) 2007-2009 OpenIntents.org
 *	OI Newsreader is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *
 *	OI Newsreader is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with OI Newsreader.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.io.InputStream;
import java.util.HashMap;

import org.droidcon.droidconapp.R;
import org.droidcon.droidconapp.news.News.Channel;
import org.droidcon.droidconapp.news.News.Contents;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.NotificationManager;
import android.app.AlertDialog.Builder;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;

public class NewsActivity extends ListActivity {

	private static final int MENU_CHANNELITEM = 1001;
	private static final int MENU_CHANNELSETTINGS = 1002;
	private static final int MENU_TAGS = 1003;
	private static final int MENU_SCAN = 1004;
	private static final int MENU_SEARCH = 1005;
	private static final int MENU_MARK_ALL_AS_READ = 1006;

	private static final int SUBMENU_CHANNELITEM_TAG = 2001;
	private static final int SUBMENU_CHANNELITEM_DELETE = 2002;
	private static final int SUBMENU_CHANNELITEM_FOLLOW = 2003;
	private static final int SUBMENU_CHANNELITEM_MAGNOLIA = 2004;
	private static final int SUBMENU_CHANNELITEM_URL = 2005;
	private static final int SUBMENU_CHANNELITEM_SHOW_CONTENT = 2006;

	private static final int SUBMENU_DEBUG_1 = 6006;

	private static final int SUBMENU_CHANNELITEM_TOGGLE = 2007;

	private static final int SUBMENU_CHANNELSETTINGS_TAG = 3001;
	private static final int SUBMENU_CHANNELSETTINGS_EDITSETTINGS = 3002;
	private static final int SUBMENU_CHANNELSETTINGS_DELETEALL = 3003;

	private static final String _TAG = "AFeedMessages";
	protected static final int CONNECTIVITY_EVENT = 10000;

	private Cursor mCursor;

	private String feedID = "";
	private String feedName = "";

	private String channelType = "0";
	private News mNews;
	private String feedLink;

	private boolean offlineMode;
	private AlertDialog mCurrentMsgDialog;
	private String feedUpdateMsgs;
	private ConnectivityManager mConnectionManager;
	private int mCurrentPosition;
	private boolean notConnected;

	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);

		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

		mNews = new News(getContentResolver());

		// Add footer
		LayoutInflater inflater = (LayoutInflater) this
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		LinearLayout footer = (LinearLayout) inflater.inflate(
				R.layout.messages_footer, null);
		Button bt = (Button) footer.findViewById(R.id.button);
		bt.setOnClickListener(new OnClickListener() {

			public void onClick(View arg0) {
				scan();
			}

		});
		getListView().setItemsCanFocus(true);
		getListView().addFooterView(footer);

		mConnectionManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
	}

	private void checkOfflineMode() {

		// Default is off:
		offlineMode = true;
		notConnected = false; // assume always online

		if (mConnectionManager != null) {
			NetworkInfo ni = mConnectionManager.getActiveNetworkInfo();
			if (ni != null) {
				Log.v(_TAG, ni.getTypeName());
				NetworkInfo.State nis = ni.getState();

				if (nis.equals(android.net.NetworkInfo.State.CONNECTED)
						|| nis.equals(android.net.NetworkInfo.State.CONNECTING)) {
					notConnected = false;
				} else {
					notConnected = true;
				}
			}
		}
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Log.d(_TAG, "Clicked at >>" + position);

		if (offlineMode) {
			showOfflineItem(position);
		} else {
			followItemLink(position);
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle icicle) {
		super.onSaveInstanceState(icicle);
		if (mCurrentMsgDialog != null && mCurrentMsgDialog.isShowing()) {
			icicle.putInt(this.getClass().getName(), mCurrentPosition);
		}
		stopManagingCursor(mCursor);
		Log.d("AFEEDLIST", "onFreeze: entering");

	}

	@Override
	protected void onRestoreInstanceState(Bundle state) {
		super.onRestoreInstanceState(state);
		int position = state.getInt(this.getClass().getName(), -1);
		if (position >= 0) {
			showOfflineItem(position);
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		Log.d(_TAG, "onResume: entering");
		checkOfflineMode();
		init();
	}

	@Override
	protected void onPause() {
		super.onPause();
	}

	private void init() {
		initFieldsFromIntent();

		mCursor = managedQuery(News.Contents.CONTENT_URI,
				News.Contents.PROJECTION_MAP, News.Contents.CHANNEL_ID + "="
						+ "=" + feedID, null, null);
		mCursor.registerDataSetObserver(new DataSetObserver() {
			@Override
			public void onChanged() {
				NewsActivity.this.setTitle(feedName + "(" + mCursor.getCount()
						+ ")");
			}
		});

		this.setTitle(feedName + "(" + mCursor.getCount() + ")");

		// always scan if no entries yet or
		// if feed is viewed directly (e.g. from browser)
		if (mCursor.getCount() == 0
				|| Intent.ACTION_VIEW.equals(getIntent().getAction())) {
			scan();
		}

		// Use our own list adapter
		setListAdapter(new MessageListAdapter(mCursor, this, channelType));

		// Add context menu
		getListView().setOnCreateContextMenuListener(
				new View.OnCreateContextMenuListener() {

					public void onCreateContextMenu(ContextMenu contextmenu,
							View view, ContextMenu.ContextMenuInfo obj) {
						contextmenu.add(0,
								NewsActivity.SUBMENU_CHANNELITEM_SHOW_CONTENT,
								0, R.string.showoffline).setIcon(
								android.R.drawable.ic_menu_info_details);

						contextmenu.add(0,
								NewsActivity.SUBMENU_CHANNELITEM_DELETE, 0,
								R.string.delete).setIcon(
								android.R.drawable.ic_menu_delete);

						// contextmenu.add(0,AFeedMessages.SUBMENU_CHANNELITEM_TAG
						// ,"Tag
						// Local",R.drawable.tagging_application001a);
						// contextmenu.add(0,
						// AFeedMessages.SUBMENU_CHANNELITEM_MAGNOLIA, 0,
						// R.string.magnolia_tagging);
						// contextmenu.add(0, AFeedMessages.SUBMENU_DEBUG_1, 0,
						// "show debug info").setIcon(
						// android.R.drawable.ic_menu_info_details);

						/*
						 * android.view.SubMenu submenu;
						 * submenu=contextmenu.addSubMenu
						 * (0,AFeedMessages.MENU_TAGS,
						 * "Tags",R.drawable.tagging_application001a);
						 * //submenu.
						 * add(0,AFeedMessages.SUBMENU_CHANNELITEM_TAG,"Tag
						 * Local",R.drawable.tagging_application001a);
						 * submenu.add
						 * (0,AFeedMessages.SUBMENU_CHANNELITEM_MAGNOLIA
						 * ,"Magnolia"
						 * ,R.drawable.tagging_magnolia_application001a);
						 */
					}

				});

		/*
		 * // Add click action getListView().setOnItemClickListener( new
		 * AdapterView.OnItemClickListener() {
		 * 
		 * @Override public void onItemClick(AdapterView parent, View v, int
		 * position, long id) { // Clicking an item starts editing it
		 * followItemLink(position); }
		 * 
		 * });
		 */
	}

	private void initFieldsFromIntent() {
		String channelUri = "http://droidcon.de/de?format=feed&type=rss";
		feedID = mNews.findChannel(Channel.CONTENT_URI, channelUri);
		feedLink = channelUri;		
		channelType = String.valueOf(News.CHANNEL_TYPE_RSS);

		Log.v(_TAG, "view: " + channelType + " " + " " + feedID + " "
				+ feedName + " " + feedLink);

		if (feedID == null) {
			HashMap map = new HashMap();
			map.put(News.Channel.CHANNEL_LINK, feedLink);

			AbstractFeedFetcherThread thread = new RSSSaxFetcherThread(map,
					mNews, this);

			InputStream is = thread.fetch();
			feedName = thread.parseTitle(is);

			ContentValues cv = new ContentValues();
			cv.put(Channel.CHANNEL_LINK, feedLink);
			cv.put(Channel.CHANNEL_TYPE, channelType);
			cv.put(Channel.CHANNEL_NAME, feedName);
			// default is 0 (= insertOnly)
			feedUpdateMsgs = String.valueOf(0);
			cv.put(News.Channel.UPDATE_MSGS, feedUpdateMsgs);

			// default is 0 (= no notification)
			cv.put(News.Channel.NOTIFY_NEW, String.valueOf(0));

			Uri newUri = mNews.insert(Channel.CONTENT_URI, cv);
			feedID = newUri.getLastPathSegment();
			Log.v(_TAG, "new id: " + channelType + " " + " " + feedID + " "
					+ feedName + " " + feedLink);

		} else {
			Cursor cursor = getContentResolver().query(
					Uri.withAppendedPath(Channel.CONTENT_URI, feedID),
					new String[] { Channel._ID, Channel.CHANNEL_TYPE,
							Channel.UPDATE_MSGS }, null, null, null);
			cursor.moveToFirst();
			channelType = cursor.getString(1);
			feedUpdateMsgs = cursor.getString(2);
			cursor.close();

			Log.v(_TAG, "old id: " + channelType + " " + " " + feedID + " "
					+ feedName + " " + feedLink);
		}

	}

	private int getChannelType(String type) {
		int result = News.CHANNEL_TYPE_RSS;
		return result;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		Log.v("AFeedMessages", "onCreateOptionsMenu:entering");

		boolean result = super.onCreateOptionsMenu(menu);
		menu.add(0, NewsActivity.MENU_SCAN, 0, R.string.update).setIcon(
				android.R.drawable.ic_menu_search);
		menu.add(0, NewsActivity.MENU_MARK_ALL_AS_READ, 0,
				R.string.markallasread);
		// .setIcon(android.R.drawable.ic_menu_search);
		return result;

	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Log.v(_TAG, "onOptionsItemSelected: item.id>>" + item.getItemId()
				+ "<<");

		super.onOptionsItemSelected(item);

		switch (item.getItemId()) {
		case MENU_SCAN:

			scan();

			break;
		case MENU_MARK_ALL_AS_READ:
			markAllAsRead();
			break;
		}
		return true;
	}

	/**
	 * requires feedId, feedLink and channelType
	 */
	private void scan() {
		setProgressBarIndeterminateVisibility(true);
		// mProgressDialog = ProgressDialog.show(this,
		// getString(R.string.update),
		// getString(R.string.update));
		new Thread() {
			@Override
			public void run() {

				HashMap<String, String> data = new HashMap();
				data.put(News.Channel._ID, feedID);
				data.put(News.Channel.CHANNEL_LINK, feedLink);
				data.put(News.Channel.UPDATE_MSGS, feedUpdateMsgs);

				AbstractFeedFetcherThread rt = new RSSSaxFetcherThread(data,
						mNews, NewsActivity.this);

				InputStream is = rt.fetch();
				if (is != null) {
					rt.parse(is);
				} else {
					runOnUiThread(new Runnable() {
						public void run() {
							Toast.makeText(NewsActivity.this,
									getString(R.string.urlfailed),
									Toast.LENGTH_LONG).show();

						}
					});
				}

				runOnUiThread(new Runnable() {
					public void run() {
						setProgressBarIndeterminateVisibility(true);
						// mProgressDialog
						// .setMessage(getString(R.string.checkicon));
					}
				});

				data = new HashMap();
				data.put(News.Channel._ID, feedID);
				data.put(News.Channel.CHANNEL_NAME, feedName);
				data.put(News.Channel.CHANNEL_LINK, feedLink);
				data.put(News.Channel.CHANNEL_TYPE, channelType);
				IconRetrieverThread iconThread = new IconRetrieverThread(
						NewsActivity.this, data);

				String iconUri = iconThread.getUri();
				iconThread.downloadIcon(iconUri);

				runOnUiThread(new Runnable() {
					public void run() {
						setProgressBarIndeterminateVisibility(false);
						// mProgressDialog.dismiss();
					}
				});

			}
		}.start();

	}

	private void markAllAsRead() {

		mNews.markFeedAsRead(Long.parseLong(feedID));

	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		super.onContextItemSelected(item);
		AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item
				.getMenuInfo();
		switch (item.getItemId()) {
		case SUBMENU_CHANNELITEM_FOLLOW:
			followItemLink(menuInfo.position);
			break;
		case SUBMENU_CHANNELITEM_SHOW_CONTENT:
			showOfflineItem(menuInfo.position);
			break;
		case SUBMENU_CHANNELITEM_TOGGLE:
			((MessageListAdapter) getListAdapter()).toggle(menuInfo.position);
			break;
		case SUBMENU_CHANNELITEM_DELETE:
			menuDelete(menuInfo.id);
			break;
		case SUBMENU_DEBUG_1:
			showDebugInfo(menuInfo.position);
			break;
		}

		return true;
	}

	private void showDebugInfo(int position) {
		Cursor cursor = (Cursor) getListAdapter().getItem(position);
		String pubDate = cursor.getString(cursor
				.getColumnIndexOrThrow(Contents.ITEM_PUB_DATE));
		String created = cursor.getString(cursor
				.getColumnIndexOrThrow(Contents.CREATED_ON));
		String id = cursor
				.getString(cursor.getColumnIndexOrThrow(Contents._ID));
		Toast.makeText(
				this,
				"Pub date: " + pubDate + "\n created: " + created + " id: "
						+ id, Toast.LENGTH_LONG).show();

	}

	private void showOfflineItem(int position) {
		Log.v(_TAG, "show offline " + position);

		mCursor.moveToPosition(position);
		SingleMessageWebView view = new SingleMessageWebView(this);
		CharSequence titel = setWebViewMessage(view, mCursor);

		Builder b = new AlertDialog.Builder(this).setView(view).setTitle(titel);

		setCurrentMessageToRead(mCursor);

		// get icon uri
		Cursor channelC = getContentResolver().query(
				Uri.withAppendedPath(Channel.CONTENT_URI, feedID),
				new String[] { Channel._ID, Channel.CHANNEL_ICON_URI }, null,
				null, null);
		String iconUri = null;
		if (channelC.moveToFirst()) {
			iconUri = channelC.getString(1);
		}
		// set dialog icon
		channelC.close();
		setIcon(b, iconUri, Integer.parseInt(channelType));

		// show dialog
		mCurrentMsgDialog = b.show();
		mCurrentPosition = position;
	}

	private void setCurrentMessageToRead(Cursor cursor) {
		ContentValues cv = new ContentValues();
		cv.put(News.Contents.READ_STATUS, News.STATUS_READ);
		mNews.update(Uri.withAppendedPath(Contents.CONTENT_URI, cursor
				.getString(mCursor.getColumnIndexOrThrow(News.Contents._ID))),
				cv, null, null);
	}

	private CharSequence setWebViewMessage(final SingleMessageWebView view,
			Cursor cursor) {
		CharSequence content = cursor.getString(cursor
				.getColumnIndexOrThrow(News.Contents.ITEM_CONTENT));
		CharSequence contentType = cursor.getString(cursor
				.getColumnIndexOrThrow(News.Contents.ITEM_CONTENT_TYPE));
		CharSequence titel = cursor.getString(cursor
				.getColumnIndexOrThrow(News.Contents.ITEM_TITLE));
		Log.v(_TAG, "show offline " + content + " " + titel);

		if (News.CONTENT_TYPE_G.equals(contentType) && !notConnected) {
			String link = cursor.getString(cursor
					.getColumnIndexOrThrow(News.Contents.ITEM_LINK));
			view.loadUrl(link);

		} else {
			view.loadUrl(Uri.withAppendedPath(
					Contents.CONTENT_URI,
					cursor.getString(cursor
							.getColumnIndexOrThrow(News.Contents._ID)))
					.toString());
		}
		view.setMessageLink(cursor.getString(cursor
				.getColumnIndexOrThrow(News.Contents.ITEM_LINK)));
		view.disableButtons(cursor.isFirst(), cursor.isLast());
		return titel;
	}

	private void setIcon(Builder b, String iconUri, int type) {

		if (iconUri == null || iconUri.equals("")) {

			b.setIcon(R.drawable.rss_icon_small);
		} else {
			try {
				b.setIcon(Drawable.createFromPath(iconUri));
			} catch (Exception e) {
				Log.e(_TAG, "error reading icon," + e.getMessage());
				b.setIcon(R.drawable.rss_icon_small);

			}

		}

	}

	private void followItemLink(int position) {

		int pos = position;
		Log.d(_TAG, "followItemLink: pos>>" + pos + "<<");
		if (pos > -1) {

			mCursor.moveToPosition(pos);
			Uri uri = null;

			String strUri = mCursor.getString(mCursor
					.getColumnIndexOrThrow(News.Contents.ITEM_LINK));
			uri = Uri.parse(strUri);

			Intent intent = new Intent(Intent.ACTION_VIEW, uri);
			startActivity(intent);
		}
	}

	private void menuDelete(long l) {

		int result = getContentResolver().delete(
				Uri.withAppendedPath(Contents.CONTENT_URI, String.valueOf(l)),
				null, null);
		Log.d(_TAG, " deletet row " + l + " >" + result);

	}

	public void showPrevious(SingleMessageWebView view) {
		mCursor.moveToPosition(mCurrentPosition);
		if (!mCursor.isFirst()) {
			mCursor.moveToPrevious();
			CharSequence title = setWebViewMessage(view, mCursor);
			mCurrentMsgDialog.setTitle(title);
			setCurrentMessageToRead(mCursor);
			mCurrentPosition--;
		}

	}

	public void showNext(SingleMessageWebView view) {
		mCursor.moveToPosition(mCurrentPosition);
		if (!mCursor.isLast()) {
			mCursor.moveToNext();
			CharSequence title = setWebViewMessage(view, mCursor);
			mCurrentMsgDialog.setTitle(title);
			setCurrentMessageToRead(mCursor);
			mCurrentPosition++;
		}

	}

}/* eoc */
